package com.jcli.fx3u;

import com.jcli.HslCommunication.Core.Types.OperateResult;
import com.jcli.HslCommunication.Core.Types.OperateResultExOne;
import com.jcli.HslCommunication.HslCommunicationDemo.DemoUtils;
import com.jcli.HslCommunication.Profinet.Melsec.MelsecA1ENet;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 演示从PLC中读取D寄存器的数据，使用Swing界面显示
 *
 * @author ljc
 * @version 1.0
 * @date 2023/11/10 20:44
 */
public class PLCDataReaderDemoWithSwing02 extends JFrame {
    private MelsecA1ENet melsecNet;
    private JTextArea textArea;
    private int readCount; // 读取计数器
    private boolean isReading; // 用于标识是否正在读取
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("[HH:mm:ss] ");

    public PLCDataReaderDemoWithSwing02() {


        // 创建Melsec A1E客户端对象并与PLC通信
        melsecNet = new MelsecA1ENet("192.168.1.11", 3000);
        // melsecNet.SetPersistentConnection();

        // 连接到 PLC 设备
        OperateResult connect = melsecNet.ConnectServer(); // 调用连接服务器的方法


        // 初始化计数器和读取状态
        readCount = 0;
        isReading = false;

        // 设置Swing界面
        setTitle("PLC Data Reader with Swing");
        setSize(1000, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel(new BorderLayout());

        textArea = new JTextArea();
        // 设置字体
        Font font = new Font("黑体", Font.BOLD, 16); // 16号粗体
        textArea.setFont(font);
        JScrollPane scrollPane = new JScrollPane(textArea);
        panel.add(scrollPane, BorderLayout.CENTER);

        JButton readButton = new JButton("Read Data");
        JButton stopButton = new JButton("Stop Reading");
        readButton.setFont(font);readButton.setFont(font);
        readButton.setEnabled(false);
        stopButton.setEnabled(false);
        panel.add(readButton, BorderLayout.WEST);
        panel.add(stopButton, BorderLayout.EAST);

        if (connect.IsSuccess) { // 如果连接成功
            // 连接成功时，显示成功消息框
            JOptionPane.showMessageDialog(
                    null,
                    "Connect Success", // 消息框的消息内容
                    "Result", // 消息框标题
                    JOptionPane.PLAIN_MESSAGE); // 消息框类型为普通消息

            // 启用内容区域的 UI 元素，通常是在连接成功后才允许用户进行其他操作
            // DemoUtils.SetPanelEnabled(panelContent, true); // 启用内容区域的UI元素
            readButton.setEnabled(true);  // 启用断开连接按钮
            // stopButton.setEnabled(true); // 禁用当前连接按钮，避免重复连接
        } else {
            // 连接失败时，显示失败消息框
            JOptionPane.showMessageDialog(
                    null,
                    "Connect Failed:" + connect.ToMessageShowString(), // 显示失败原因
                    "Result", // 消息框标题
                    JOptionPane.WARNING_MESSAGE); // 消息框类型为警告消息
            readButton.setEnabled(false);  // 启用断开连接按钮
            stopButton.setEnabled(false); // 禁用当前连接按钮，避免重复连接
        }

        readButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                startReading();
                readButton.setEnabled(false);
                stopButton.setEnabled(true);
            }
        });

        stopButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                stopReading();
                readButton.setEnabled(true);
                stopButton.setEnabled(false);
            }
        });

        add(panel);

        // 将窗口设置为屏幕中央
        setLocationRelativeTo(null);
    }

    /**
     * 开始读取PLC的D寄存器数据
     */
    private void startReading() {
        if (!isReading) {
            isReading = true;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (isReading) {
                        readAndPrintData();
                        try {
                            Thread.sleep(2000); // 读取间隔，可以根据需要调整
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }

    /**
     * 停止读取PLC的D寄存器数据
     */
    private void stopReading() {
        isReading = false;
        // closeConnection(); // 关闭连接
        textArea.append("停止读取\n");
    }

    private void closeConnection() {
        if (melsecNet != null) {
            melsecNet.ConnectClose();
        }
    }

    /**
     * 读取并打印PLC的D寄存器数据
     */
    private void readAndPrintData() {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                textArea.append(dateFormat.format(new Date()) + "第 " + (++readCount) + " 次读取\n");
                long startTime = System.currentTimeMillis();
                //    读取并打印数据的逻辑提取为一个方法
                readAndPrintSingleData("D1");
                readAndPrintSingleData("D31");
                readAndPrintSingleData("D61");
                readAndPrintSingleData("D91");
                readAndPrintSingleData("D121");
                readAndPrintSingleData("D151");
                readAndPrintSingleData("D181");
                readAndPrintSingleData("D211");
                long endTime = System.currentTimeMillis();
                textArea.append(dateFormat.format(new Date()) + "本次读取耗时: " + (endTime - startTime) + " ms\n");
                textArea.append("\n");
            }
        });

    }

    /**
     * 读取并打印寄存器数据
     *
     * @param address
     */
    private void readAndPrintSingleData(String address) {
        // 读取D寄存器的数据
        OperateResultExOne<int[]> readResult7 = melsecNet.ReadInt32(address, (short) 30);
        // 打印读取结果
        if (readResult7.IsSuccess) {
            printIntArray(readResult7.Content);
        } else {
            textArea.append("读取失败\n");
        }
    }

    /**
     * 打印int数组的值
     *
     * @param data int数组
     */
    private void printIntArray(int[] data) {
        for (int value : data) {
            textArea.append(value + " ");
        }
        textArea.append("\n");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                PLCDataReaderDemoWithSwing02 demo = new PLCDataReaderDemoWithSwing02();
                demo.setVisible(true);
            }
        });
    }
}
